﻿using System;
using System.Collections.Generic;
using System.Configuration.Install;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using Microsoft.Win32;

namespace WP7Config
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class wndConfig : Window
    {
        private const string COMPANY = "PGMariotti.net";
        private const string PRODUCT_NAME = "WP7 Print Helper Service";
        private const string MODULE_NAME = "Configuration";
        private string sDir;

        private static List<string> eStrings = new List<string>
        { "Back", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "Delete", "End", "Home", 
            "Insert", "Left", "NumPad0", "NumPad1", "NumPad2", "NumPad3", "NumPad4", "NumPad5",
            "NumPad6", "NumPad7", "NumPad8", "NumPad9", "Right" };

        public wndConfig()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            string sExec = Assembly.GetExecutingAssembly().Location;
            int i = sExec.LastIndexOf("\\");
            sDir = sExec.Substring(0, i) + "\\";
            if (!IsKey())
            {
                tbPort.Text = "8000";
            }
            else
                tbPort.Text = GetSetting("Port", "8000");
        }
        
        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            SaveSetting("Port", tbPort.Text);
            SaveSetting("Directory", sDir);
            if ((bool)cbStopStart.IsChecked)
            {
                ServiceController service = new ServiceController();
                service.ServiceName = "PrintService";
                if (service.Status == ServiceControllerStatus.Running)
                {
                    RestartService("PrintService", 10000);
                }
                else
                {
                    StartService("PrintService", 10000);
                }
            }
            this.DialogResult = true;
            this.Close();
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.Close();
        }

        private void tbPort_KeyDown(object sender, KeyEventArgs e)
        {
            if (eStrings.Contains(e.Key.ToString()))
            {
                e.Handled = false;
                return;
            }
            System.Media.SystemSounds.Beep.Play();
            e.Handled = true;
        }

        private void tbPort_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (tbPort.Text == string.Empty)
                btnOK.IsEnabled = false;
            else
            {
                int i = Convert.ToInt32(tbPort.Text);
                if ((i > 65536) || (i == 0))
                {
                    MessageBox.Show(MODULE_NAME + "- The value entered for the I/O port is outside the range 1 to 65535");
                    btnOK.IsEnabled = false;
                }
                else
                    btnOK.IsEnabled = true;
            }
        }

        #region Service Functions

        public static void StartService(string serviceName, int timeoutMilliseconds)
        {
            ServiceController service = new ServiceController(serviceName);
            try
            {
                TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

                service.Start();
                service.WaitForStatus(ServiceControllerStatus.Running, timeout);
                MessageBox.Show("Service " + serviceName + " has started.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(MODULE_NAME + "Start service\n" + ex.Message);
                System.Windows.Application.Current.Shutdown();
            }
        }

        public static bool StopService(string serviceName, int timeoutMilliseconds)
        {
            ServiceController service = new ServiceController(serviceName);
            if (service.Status == ServiceControllerStatus.Stopped)
                return true;
            try
            {
                TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
                MessageBox.Show("Service " + serviceName + " has stopped.");
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(MODULE_NAME + "Stop service\n" + ex.Message);
                return false;
            }
        }

        public static void RestartService(string serviceName, int timeoutMilliseconds)
        {
            ServiceController service = new ServiceController(serviceName);
            try
            {
                int millisec1 = Environment.TickCount;
                TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
                MessageBox.Show("Service " + serviceName + " has stopped.");

                // count the rest of the timeout
                int millisec2 = Environment.TickCount;
                timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1));

                service.Start();
                service.WaitForStatus(ServiceControllerStatus.Running, timeout);
                MessageBox.Show("Service " + serviceName + " has started.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(MODULE_NAME + "Stop and restart service" + ex.Message);
                System.Windows.Application.Current.Shutdown();
            }
        }

        #endregion

        #region Registry Functions
        public static bool IsKey()
        {
            RegistryKey reg_key;
            try
            {
                String szKey = "SOFTWARE\\" + COMPANY + "\\" + PRODUCT_NAME + "\\" + MODULE_NAME;
                reg_key = Registry.LocalMachine.OpenSubKey(szKey);
                if (reg_key != null)
                    return true;
                else
                    return false;
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Configuration - GetSetting" + ex.Message);
                System.Windows.Application.Current.Shutdown();
            }
            return false;
        }
        public static object GetSetting(string key, object default_value)
        {

            RegistryKey reg_key = Registry.LocalMachine.OpenSubKey("Software", true);
            try
            {
                RegistryKey reg_key1 = reg_key;
                String szKey = COMPANY + "\\" + PRODUCT_NAME + "\\" + MODULE_NAME;
                reg_key = reg_key1.OpenSubKey(szKey, true);
                if (reg_key != null)
                    return reg_key.GetValue(key, default_value);
                else
                    return default_value;
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(MODULE_NAME + "- GetSetting" + ex.Message);
                System.Windows.Application.Current.Shutdown();
            }
            return default_value;
        }
        public static string GetSetting(string key, string default_value)
        {
            return (string)GetSetting(key, (object)default_value);
        }
        public static int GetSetting(string key, int default_value)
        {
            return (int)GetSetting(key, (object)default_value);
        }
        public static bool GetSetting(string key, bool default_value)
        {
            string ret = GetSetting(key, null);
            if (ret == null) return default_value;
            if (ret == "True")
                return true;
            else
                return false;
        }

        public static void SaveSetting(string key, object val)
        {
            try
            {
                RegistryKey reg_key = Registry.LocalMachine.OpenSubKey("Software", true);
                RegistryKey reg_key1 = reg_key; 
                String szKey = COMPANY + "\\" + PRODUCT_NAME + "\\" + MODULE_NAME;
                reg_key = reg_key1.OpenSubKey(szKey, true);
                if (reg_key == null)
                {
                    reg_key = reg_key1.CreateSubKey(szKey);
                }
                reg_key.SetValue(key, val);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(MODULE_NAME + "- SaveSetting" + ex.Message);
                System.Windows.Application.Current.Shutdown();
            }
        }

        public static void DeleteSettings()
        {
            try
            {
                RegistryKey reg_key = Registry.LocalMachine.OpenSubKey("Software", true);
                RegistryKey reg_key1 = reg_key;
                String szKey = COMPANY + "\\" + PRODUCT_NAME + "\\" + MODULE_NAME;
                reg_key1.DeleteSubKeyTree(szKey, false);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(MODULE_NAME + "- SaveSetting" + ex.Message);
                System.Windows.Application.Current.Shutdown();
            }
        }
        #endregion

    }
}
